#ifndef TEST_TWO_METHOD_H_
#define TEST_TWO_METHOD_H_
#include "Arcroll.h"
#include "detect_earthwork.h"
#include <Mesh_IO/Mesh_IO.h>
static Viewer_Something* test_show_points_set1(Viewer_World*vw,float* points,int len)
{
    Node* n=vw->create_something(vw,"Points");
    Viewer_Something*vs=(Viewer_Something*)(n->value);
    Viewer_Points*vp= (Viewer_Points*)(vs->evolution);
    vp->pointsize=10.0;
    vp->Data_rows=len/3;
    vp->Data=(float*)malloc(sizeof(float)*len);
    vp->set_color(vp,0.9,0.9,0.9,1.0);
    for(int i=0;i<len;i++)
    {
        vp->Data[i]=points[i];
    }
    
    free_node(n);
    return vs;
}
typedef struct TTM{
    Node* select_ps;
    double* triangles;int len1;
    float*points;int len2; 
    Viewer_Opengl_Interpreter*voi;
    Viewer_Something* vs;

}TTM;
static inline void ttm_init(TTM* ttm)
{
    ttm->select_ps=NULL;
    ttm->triangles=NULL;
    ttm->points=NULL;
    ttm->len1=0;
    ttm->len2=0;
    ttm->voi=NULL;
    ttm->vs=NULL;
}
void viewer_ttm_mouse_button_callback(Viewer_Intera* mi)
{
    Interactor_GlobalInfo* g_info=mi->g_info;
    TTM* ttm=(TTM*)(mi->representation); 
    //printf("%d\n",g_info->mouse_button);
    if(g_info->mouse_button==VIEWER_MOUSE_BUTTON_LEFT&&g_info->mouse_action==1 && g_info->ipi.vs!=NULL&&g_info->key==VIEWER_KEY_S)
    {
        Viewer_Something*vs=(Viewer_Something*)(g_info->ipi.vs);
        printf("xuanzhong\n"); 
        Viewer_Points* vp=(Viewer_Points*)(vs->evolution);
        vp->color[g_info->ipi.marked_element*4+0]=0.0;
        ttm->voi->update_data(ttm->voi);
        float *pp=&(vp->Data[g_info->ipi.marked_element*3]) ;
        ttm->select_ps=node_overlying(ttm->select_ps,pp);
        printf("%lf %lf %lf\n",pp[0],pp[1],pp[2]);


        //printf("%s name_id:%d marked_id: %d\n",g_info->ipi.vs->name,g_info->ipi.vs->name_id,g_info->ipi.marked_element);

        //printf("pick something name:%s id:%d marked_element:%d\n",vs->name,vs->id,vs->marked_element);
    }
    
}

double*   compute_volume_difference_of_two_mesh( double* m1,int len_m1,double*ps ,int len );
void viewer_ttm_key_callback(Viewer_Intera*mi)
{
    Interactor_GlobalInfo* g_info=mi->g_info;
    TTM* ttm=(TTM*)(mi->representation);  
    if(g_info->key_action==VIEWER_PRESS&&g_info->key==VIEWER_KEY_G&&ttm->select_ps!=NULL)
    {
        //printf("key  g \n"); 
        double* ps=(double*)malloc(sizeof(double)*3*node_size(ttm->select_ps));
        float* ps1=(float*)malloc(sizeof(float)*3*node_size(ttm->select_ps));

        double minx=((float*)(ttm->select_ps->value))[0] ,miny= ((float*)(ttm->select_ps->value))[1];

        double maxx=minx,maxy=miny;
        int i=0;
        for(Node* nit=ttm->select_ps;nit!=NULL;nit=(Node*)(nit->Next))
        {
            ps[i*3+0]=((float*)(nit->value))[0];ps[i*3+1]=((float*)(nit->value))[1];ps[i*3+2]=((float*)(nit->value))[2];
            ps1[i*3+0]=((float*)(nit->value))[0];ps1[i*3+1]=((float*)(nit->value))[1];ps1[i*3+2]=((float*)(nit->value))[2];
            if(ps[i*3+0]>maxx)
            {
                maxx=ps[i*3+0];
            }
            else if(ps[i*3+0]<minx)
            {
                minx=ps[i*3+0];
            }
            if(ps[i*3+1]>maxy)
            {
                maxy=ps[i*3+1];
            }
            else if(ps[i*3+1]<miny)
            {
                miny=ps[i*3+1];
            }
            i++;
        }

        
        ps[0]=minx;ps[1]=miny; 
        ps[3]=minx;ps[4]=maxy;
        ps[6]=maxx;ps[7]=miny; 
        ps[9]=maxx;ps[10]=maxy;
        ps1[0]=minx;ps1[1]=miny; 
        ps1[3]=minx;ps1[4]=maxy;
        ps1[6]=maxx;ps1[7]=miny; 
        ps1[9]=maxx;ps1[10]=maxy;

        double*re= compute_volume_difference_of_two_mesh(ttm->triangles,ttm->len1,ps,node_size(ttm->select_ps)*3);
       
        float result;
        int select_value_count;
        float select_values[90000]; 
        clip_points_with_volume(ttm->points,ttm->len2,ps1, node_size(ttm->select_ps)*3, select_values, &select_value_count, &result);


        printf("ratio:%lf\n",re[0]/result);
        free(re);

        free(ps);free(ps1);
        free_node(ttm->select_ps);
        ttm->select_ps=NULL;  

        // Viewer_Something*vs=(Viewer_Something*)(g_info->ipi.vs);
        // //printf("xuanzhong\n"); 
        Viewer_Points* vp=(Viewer_Points*)(ttm->vs->evolution); 
        vp->set_color(vp,0.9,0.9,0.9,1.0);
        ttm->voi->update_data(ttm->voi);
    }

} 

void test_two_method(char* mesh_file,char* points_file )
{
    Mesh mesh1,mesh2;
    Mesh_init(&mesh1);Mesh_init(&mesh2);
    _ReadOff_(&mesh1,mesh_file,3);_ReadOff_(&mesh2,points_file,3);
    Node*node_triangles=NULL;

    for(auto cit=mesh1.c_begin(&mesh1);cit!=mesh1.c_end(&mesh1);cit++)
    {
        double* triangle=(double*)malloc(sizeof(double)*9);
        for(int i=0;i<3;i++)
        {
            triangle[i*3+0] =quote(cit)->vertices[i]->point[0]; 
            triangle[i*3+1] =quote(cit)->vertices[i]->point[1]; 
            triangle[i*3+2] =quote(cit)->vertices[i]->point[2]; 
        }
        node_triangles=node_overlying(node_triangles,triangle);
    } 

    double* triangles=(double*)malloc(sizeof(double)*9*node_size(node_triangles));
    int sum=0;
    for(Node*nit= node_triangles;nit!=NULL;nit=(Node*)(nit->Next))
    {
        memmove(&triangles[sum*9],nit->value,sizeof(double)*9); 
        sum++;
    }  
    printf("len :%d\n",sum*9);

    float* points=(float*)malloc(sizeof(float)*3*mesh2.num_v(&mesh2));
    sum=0;
    for(auto vit=mesh2.v_begin(&mesh2);vit!=mesh2.v_end(&mesh2);vit++)
    {
        points[sum*3+0]=quote(vit)->point[0];points[sum*3+1]=quote(vit)->point[1];points[sum*3+2]=quote(vit)->point[2];
        sum++;
    }

    Viewer_World_Manager vwm;
    viewer_world_manager_init(&vwm);

    Viewer_Opengl_Interpreter voi;
    Viewer_World *vw=vwm.create_world(&vwm,NULL);

    add_default_somethings(vw);  

    
    Viewer_Something* vs1= test_show_points_set1(vw,points,mesh2.num_v(&mesh2)*3);
    
    Node*n=vw->create_something(vw,"Intera");
    Viewer_Something* vs=(Viewer_Something*)(n->value);
    Viewer_Intera*vi=(Viewer_Intera*)(vs->evolution);
    TTM* ttm=(TTM*)malloc(sizeof(TTM));
     
    ttm_init(ttm);
    ttm->points=points;
    ttm->triangles=triangles;
    ttm->len1=mesh1.num_c(&mesh1)*9;
    ttm->len2=mesh2.num_v(&mesh2)*3;
    ttm->voi=&voi;
    ttm->vs=vs1 ;
    vi->representation=(void*)ttm;
   
    vi->mouse_button_callback=viewer_ttm_mouse_button_callback;
    vi->key_callback=viewer_ttm_key_callback; 

    free_node(n); 
    //test_show_mesh_triangles(vw,node_triangles);
    //test_show_triangles_set(vw,&re[2],re[1]);
    //test_show_points_set(vw,&re[2],re[1]);

    viewer_opengl_interpreter_initn(&voi,&vwm);
    voi.interpreter(&voi);


    viewer_opengl_interpreter_free(&voi);
    viewer_world_manager_free(&vwm); 

    free(triangles);
    free(points);
    free_node(node_triangles);
    Mesh_free(&mesh1);Mesh_free(&mesh2);
}






#endif